package graphics.rasterizing.model;

import static util.MatrixOperationsF.cloo;
import static util.MatrixOperationsF.multiply;
import graphics.rasterizing.TransformedTriangle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Stack;

import util.Transformations;

public class SimpleSceneGraph {
	private float[][] transformation;
	private Collection<SimpleSceneGraph> _graph = new ArrayList<SimpleSceneGraph>();

	public static class Tri extends SimpleSceneGraph {
		public Tri(Collection<Triangle> tri, float[][] transformation) {
			super(transformation);
			this.triangle = tri;
		}

		@Override
		protected void make_collection(float[][] fs,
				java.util.ArrayList<Triangle> buffer) {
			Tri leaf = (Tri) this;
			for (Triangle triangle : leaf.triangle)
				buffer.add(new TransformedTriangle(triangle, fs));
			return;
		};

		Collection<Triangle> triangle;

	}

	public SimpleSceneGraph(float[][] transformation) {
		this.transformation = cloo(transformation);
	}

	public Collection<Triangle> getIterator() {
		ArrayList<Triangle> t = new ArrayList<Triangle>();
		this.make_collection(Transformations.ones(4), t);
		return make_coll(this);
	}

	public void add(SimpleSceneGraph g) {
		_graph.add(g);
	}

	// TODO:think this over
	private static Collection<Triangle> make_coll(SimpleSceneGraph origin) {
		class node {
			node(SimpleSceneGraph g, float[][] f) {
				this.g = g;
				this.buffer = f;
			}

			final SimpleSceneGraph g;
			final float[][] buffer;
		}
		Collection<Triangle> t = new ArrayList<Triangle>();
		node current = null;
		Stack<node> stack = new Stack<node>();
		stack.add(new node(origin, origin.transformation));
		while (!stack.isEmpty()) {
			current = stack.pop();
			if (current.g instanceof Tri) {
				Tri trie = (Tri) current.g;
				for (Triangle triangle : trie.triangle)
					t.add(new TransformedTriangle(triangle, current.buffer));
			}
			for (SimpleSceneGraph g : current.g._graph) {
				stack.add(new node(g,
						multiply(current.buffer, g.transformation)));
			}
		}
		return t;
	}

	protected void make_collection(float[][] fs, ArrayList<Triangle> buffer) {
		for (SimpleSceneGraph graph : _graph)
			graph.make_collection(multiply(fs, transformation), buffer);

	}

}
